#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/3/25 14:56
# @Author  : Grayson Liu
# @Email   : graysonliu@foxmail.com
# @File    : main.py

import sys
from PyQt5.Qt import *
from PyQt5 import QtCore

from MethodList import MethodList

from ui.Ui_MainWindow import Ui_MainWindow

from ViewGraphicsForm import ViewGraphicsForm
from WelcomeForm import WelcomeForm
from ProjectForm import ProjectForm
from ParaExpForm import ParaExpForm
from ViewPlanetNDVIForm import ViewPlanetNDVIForm


class MainWindow(QMainWindow, Ui_MainWindow):
    """
    可视化平台主窗体类
    """
    # 不同功能Widget对应的标号
    widget_dic = {
        "default": 0,
        "Project": 1,
        "ParaExp": 2,
        "ViewGraphics": 3,
        "ViewPlanetNDVI": 4
    }

    def __init__(self, parent=None):
        """
        初始化主窗体类
        :param parent: 父窗体
        """
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)

        # 将MainWindow UI中 中心部分Widget设定为堆叠布局，根据选择的功能进行切换，显示不同的Widget
        self.replaceableWidget = QStackedLayout(self.functionView)

        # TODO: 在这里实例化不同功能Widget的class，使用self.replaceableWidget.addWidget(...)添加到布局中
        # 序号0，欢迎界面
        self.welcome_form = WelcomeForm()
        self.replaceableWidget.addWidget(self.welcome_form)
        # 序号1，工程界面 新建工程和打开工程
        self.project_form = ProjectForm()
        self.replaceableWidget.addWidget(self.project_form)
        # 序号2，参数实验界面 新建参数实验和打开参数实验
        self.para_exp_form = ParaExpForm()
        self.replaceableWidget.addWidget(self.para_exp_form)
        # 序号3，查看遥感影像界面 工具栏
        self.view_graphics_form = ViewGraphicsForm()
        self.replaceableWidget.addWidget(self.view_graphics_form)
        # 序号4，查看NDVI时序图界面 工具栏
        self.view_planet_ndvi_form = ViewPlanetNDVIForm()
        self.replaceableWidget.addWidget(self.view_planet_ndvi_form)

        # 设定默认状态下的index
        self.replaceableWidget.setCurrentIndex(0)

        # 关联Menu选项卡的信号和槽
        self.actionNewProject.triggered.connect(self.new_project_task)
        self.actionOpenProject.triggered.connect(self.open_project_task)
        self.actionParaExp.triggered.connect(self.paraexp_task)

        self.actionSave.triggered.connect(self.save_project_task)
        self.actionSaveAs.triggered.connect(self.saveas_project_task)

        self.actionBackWelcomeForm.triggered.connect(self.back_welcome_task)

        self.actionViewGraphics.triggered.connect(self.view_graphics_task)
        self.actionViewPlanetNDVI.triggered.connect(self.view_graphic_ndvi_task)

        self.actionAbout.triggered.connect(self.show_about_task)
        self.actionGuide.triggered.connect(self.show_help_task)

        # 将一些按钮设定为不可用状态
        self.actionSave.setEnabled(False)  # 保存按钮 不可用
        self.actionSaveAs.setEnabled(False)  # 另存为按钮 不可用

    def new_project_task(self):
        """
        新建工程菜单项的槽函数
        :return:
        """
        # 打开文件浏览器，新建工程文件.prj
        project_path, project_type = QFileDialog.getSaveFileName(self, "选择工程文件保存位置", filter="Project Files(*.prj)")
        if project_path == "":
            return
        # 打开对话框输入工程名
        project_name, flag = QInputDialog.getText(self, "工程名", "请输入工程名", text="default project")
        if not flag:
            return

        # 对ProjectForm中的MethodList对象，进行初始化设置
        self.project_form.init_method_list(project_name, project_path)

        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["Project"]
        self.replaceableWidget.setCurrentIndex(index)

        # 将一些按钮设为可用
        self.actionSave.setEnabled(True)  # 保存按钮 可用
        self.actionSaveAs.setEnabled(True)  # 另存为按钮 可用

    def open_project_task(self):
        """
        打开工程菜单项的槽函数
        :return:
        """
        project_path, project_type = QFileDialog.getOpenFileName(self, "选择工程文件", filter="Project Files(*.prj)")
        if project_path == "":
            return
        # 读取文件信息
        method_list = self.project_form.get_method_list()  # 从ProjectForm中MethodList对象
        method_list.load_project(project_path)  # 从文件中读取信息
        # 对ProjectForm中的MethodList对象，进行设置
        self.project_form.set_method_list(method_list)  # 传回ProjectForm进行处理

        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["Project"]
        self.replaceableWidget.setCurrentIndex(index)

        # 将一些按钮设为可用
        self.actionSave.setEnabled(True)  # 保存按钮 可用
        self.actionSaveAs.setEnabled(True)  # 另存为按钮 可用

    def paraexp_task(self):
        """
        开始参数实验菜单项的槽函数
        :return:
        """
        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["ParaExp"]
        self.replaceableWidget.setCurrentIndex(index)

    def save_project_task(self):
        """
        保存菜单项的槽函数
        :return:
        """
        self.project_form.save_project()

    def saveas_project_task(self):
        """
        另存为菜单项的槽函数
        :return:
        """
        self.project_form.saveas_project()

    def view_graphics_task(self):
        """
        切换replaceableWidget对应Widget的槽函数
        :return:
        """
        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["ViewGraphics"]
        self.replaceableWidget.setCurrentIndex(index)

    def view_graphic_ndvi_task(self):
        """
        切换replaceableWidget对应Widget的槽函数
        :return:
        """
        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["ViewPlanetNDVI"]
        self.replaceableWidget.setCurrentIndex(index)

    def back_welcome_task(self):
        """
        切换replaceableWidget对应Widget的槽函数
        :return:
        """
        # 禁用“保存”和“另存为”按钮
        self.actionSave.setEnabled(False)
        self.actionSaveAs.setEnabled(False)
        # 根据信号来源，从dic中找到对应的标号，切换当前显示的Widget
        index = MainWindow.widget_dic["default"]
        self.replaceableWidget.setCurrentIndex(index)

    def show_help_task(self):
        """
        显示“使用帮助”对话框
        :return:
        """
        help_str = ("使用帮助：\n"
                    "· 新建工程/打开工程：设定一组遥感影像自动化处理流程，包括遥感影像的读取、预处理、图像处理和输出，用于方便地进行农田边界提取实验。\n"
                    "· 新建参数实验/打开参数实验：对于已经建立的工程，选取某一参数进行研究，指定参数的变化范围，生成一系列的工程并批量运行处理。\n"
                    "· 查看遥感影像：显示遥感影像和地理信息，同时可以进行格式转换。\n"
                    "· 查看NDVI时序图：针对Planet卫星影像数据，可视化展现不同时期的NDVI数值，以折线图的方式呈现。\n"
                    )
        QMessageBox.about(self, "使用说明", help_str)

    def show_about_task(self):
        """
        显示“关于本程序”对话框
        :return:
        """
        QMessageBox.about(self, "关于本程序", "版本：1.0\n\n南京农业大学人工智能学院 刘通宇")


# 程序入口
if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)  # 适应高分辨率屏幕

    app = QApplication(sys.argv)
    window = MainWindow()  # 显示MainWindow，进入循环
    window.show()
    sys.exit(app.exec_())
